package com.world.cat.service.sys;

import com.world.cat.app.AppConstant;
import com.world.cat.dao.sys.RoleDao;
import com.world.cat.dao.sys.TokenInfoDao;
import com.world.cat.dao.sys.UserDao;
import com.world.cat.dao.sys.UserRoleDao;
import com.world.cat.model.sys.Role;
import com.world.cat.model.sys.User;
import com.world.cat.model.sys.UserRole;
import com.world.cat.service.generate.FieldService;
import com.world.common.pojo.ApiResult;
import com.world.common.pojo.Result;
import com.world.common.util.AES;
import com.world.common.util.CollectionUtil;
import com.world.common.util.SysUtil;
import com.world.core.dao.GenericRepository;
import com.world.core.dao.Restrictions;
import com.world.core.dao.SimpleExpression;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Transactional
public class UserService extends BaseService<User> {
    private static final Logger logger = Logger.getLogger(UserService.class);

    public static Map<String, User> userMap = new ConcurrentHashMap<>();
    public static Map<String, User> usernameUserMap = new ConcurrentHashMap<>();

    @Resource
    private UserDao userDao;
    @Resource
    private UserRoleDao userRoleDao;
    @Resource
    private RoleDao roleDao;

    @Override
    public GenericRepository getDao() {
        return userDao;
    }

    public User findByUsername(String username) {
        return userDao.findByUsername(username);
    }

    public void save(User user) {
        userDao.save(user);
    }

    public Result save(Class clazz, String jsonParams) throws Exception {
        JSONObject jsonObject = JSONObject.fromObject(jsonParams);
        Result result = BaseService.validateJsonParams(clazz, jsonObject);
        if (!result.isSuccess()) {
            return result;
        }
        User entity = initObjectByJsonParams(clazz, jsonObject);
        if (SysUtil.isEmpty(entity.getId())) {
            User user = userDao.findByUsername(entity.getUsername());
            if (user != null) {
                return new Result(false, "用户名已经存在");
            }
        }
        User tDb = (User) getDao().save(entity);
        UserService.userMap.put(tDb.getId(), tDb);
        usernameUserMap.put(tDb.getUsername(), tDb);
        return new Result(true, "成功", tDb);
    }

    public Page<User> getUserPage(Pageable pageable, String username) {
        List<SimpleExpression> expressionList = new ArrayList<SimpleExpression>();
        if (StringUtils.isNotEmpty(username)) {
            JSONObject jsonObject = JSONObject.fromObject(username);
            String username1 = jsonObject.get("username") == null ? null : jsonObject.get("username").toString();
            if (SysUtil.isNotEmpty(username1)) {
                expressionList.add(Restrictions.eq("username", username1, true));
            }
        }
        return userDao.findByPage(expressionList, pageable);
    }

    public User findById(String id) {
        return userDao.findOne(id);
    }

    public String findAll() {
        List list = userDao.findByHql("select count(*) from User");
        String count = "0";
        if (CollectionUtil.isNotEmpty(list)) {
            count = list.get(0).toString();
        }
        return count;
    }

    public ApiResult validateToken(String token) {
        /*ApiResult result = new ApiResult();
        result.setStatus(0);
        result.setData(token);
        return result;*/
        ApiResult result = new ApiResult(-1);
        if (SysUtil.isEmpty(token)) {
            result.setMessage("token 不能为空");
            return result;
        }
        String decryptStr = AES.decrypt(token, AppConstant.encryptKey);
        if (SysUtil.isEmpty(decryptStr) || !decryptStr.contains(",")) {
            result.setMessage("token 不合法");
            return result;
        }
        String[] values = decryptStr.split(",");
        String value = null;
        if (values != null && values.length == 3) {
            value = TokenInfoService.tokenMap.get(values[0]);
        } else {
            value = TokenInfoService.tokenMap.get(values[0]);
        }

        if (value == null) {
            result.setMessage("token 不合法");
            return result;
        }
        result.setStatus(1);
        result.setData(values[0]);
        return result;
    }

    public void del(String[] ids) {
        List<User> users = userDao.findByIdIn(Arrays.asList(ids));
        userDao.delete(users);
        for (User user : users) {
            UserService.userMap.remove(user.getId());
            UserService.usernameUserMap.remove(user.getUsername());
        }
    }

    public Result modifyPassword(String username, String oldPassword, String newPassword, String rePassword) {
        User user = userDao.findByUsername(username);
        if (user == null) {
            return new Result(false, "用户不存在");
        }
        if (SysUtil.isEmpty(newPassword)) {
            return new Result(false, "新密码不能为空");
        }
        if (!newPassword.equals(rePassword)) {
            return new Result(false, "两次书写的密码不一致");
        }
        if (!user.getPassword().equals(oldPassword)) {
            return new Result(false, "原密码错误");
        } else {
            user.setPassword(newPassword);
            userDao.save(user);
        }

        return new Result(true, "密码修改成功");
    }

    public void initUserCache() {
        logger.info("初始化用户数据开始");
        List<User> users = userDao.findAll();
        if (CollectionUtil.isNotEmpty(users)) {
            for (User user : users) {
                userMap.put(user.getId(), user);
                usernameUserMap.put(user.getUsername(), user);
            }
        }
        logger.info("初始化用户数据结束");
    }

    public Result getUserRoles(String id) {
        if (SysUtil.isEmpty(id)) {
            return new Result(false, "用户不存在");
        }
        User user = userDao.getOne(id);
        if (user == null) {
            return new Result(false, "用户不存在");
        }
        List<Map<String, String>> roleMapList = new ArrayList<>();
        List<Role> roles = roleDao.findAll();
        List<UserRole> userRoles = userRoleDao.findByUserId(user.getId());
        Set<String> roleIdSet = new HashSet<>();
        if (CollectionUtil.isNotEmpty(userRoles)) {
            for (UserRole userRole : userRoles) {
                roleIdSet.add(userRole.getRoleId());
            }
        }
        if (CollectionUtil.isNotEmpty(roles)) {
            for (Role role : roles) {
                Map<String, String> map = new HashMap<>();
                map.put("id", role.getId());
                if (roleIdSet.contains(role.getId())) {
                    map.put("checked", "true");
                } else {
                    map.put("checked", "false");
                }
                map.put("roleKey", role.getRoleKey());
                map.put("roleName", role.getRoleName());
                roleMapList.add(map);
            }
        }

        return new Result(true, "", roleMapList);
    }

    public Page findHandlerPage(Class clazz, String jsonParams, Pageable pageable) throws Exception {
        List<SimpleExpression> expressionList = BaseService.getExpressionByJsonParams(clazz, jsonParams);
        expressionList.add(new SimpleExpression("username", "(select distinct u.username from User u,UserRole ur,Role r where u.id=ur.userId and ur.roleId=r.id and r.roleKey='ROLE_BUSI_HANDLER')", SimpleExpression.Operator.SUB_QUERY_IN));
        Page page = getDao().findByPage(expressionList, pageable);
        return page;
    }

    public void saveAvatar(String username, String avatarUrl) {
        User user = userDao.findByUsername(username);
        user.setAvatar(avatarUrl);
        userDao.save(user);
    }
}
